/* **********************************************************************************
 *
 * Copyright (c) TMF.AscendedThemeKit.Unthemed.NET Project. All rights reserved.
 *
 * This source code is subject to terms and conditions of the Shared Source License
 * for TMF.AscendedThemeKit.Unthemed. A copy of the license can be found in the License.html file
 * at the root of this distribution. If you can not locate the Shared Source License
 * for TMF.AscendedThemeKit.Unthemed, please send an email to ascend_adm@hotmail.com.
 * By using this source code in any fashion, you are agreeing to be bound by
 * the terms of the Shared Source License for TMF.AscendedThemeKit.Unthemed.NET.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * **********************************************************************************/

using TMF.AscendedThemeKit.Unthemed.Resources;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel.Design;

namespace TMF.AscendedThemeKit.Unthemed.Windows.Forms
{
    /// <summary>
    /// Represents a Windows caption control with a gradient background.
    /// </summary>
    [ToolboxBitmap(typeof(GradientCaption), "GradientCaption.ico")]
#if GENERAL_RELEASE
    [Designer(typeof(Ascend.Windows.Forms.Design.GradientCaptionDesigner), typeof(IDesigner))]
#else
    [Designer("TMF.AscendedThemeKit.Unthemed.Windows.Forms.Design.GradientCaptionDesigner, TMF.AscendedThemeKit.Unthemed.Design.v1.5, Culture=neutral, PublicKeyToken=5123e2ac4258b06a", typeof(IDesigner))]
#endif
    [DesignerCategory("Form")]
    [ResourceDescriptionAttribute("GradientCaptionDescription")]
    public class GradientCaption : GradientPanel
    {
        private ImageList _imageList;
        private int _imageIndex;
        private string _imageKey = string.Empty;
        private bool _disposed;
        private bool _isAnimating;
        private bool _allowAnimation;
        private bool _hidePrefix;

        /// <summary>
        /// Occurs when the Image property changes. 
        /// </summary>
        [ResourceDescriptionAttribute("ImageChangedEventDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameImageChanged")]
        public event EventHandler ImageChanged;

        /// <summary>
        /// Occurs when the ImageAlign property changes.
        /// </summary>
        [ResourceDescriptionAttribute("ImageAlignChangedEventDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameImageAlignChanged")]
        public event EventHandler ImageAlignChanged;

        /// <summary>
        /// Occurs when the TextAlign property changes.
        /// </summary>
        [ResourceDescriptionAttribute("TextAlignChangedEventDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameTextAlignChanged")]
        public event EventHandler TextAlignChanged;

        /// <summary>
        /// Gets a value indicating whether the control is allowed to animate the image.
        /// </summary>
        /// <value>
        /// 	<para>
        /// true if the control is allowed to animate; otherwise, false.
        /// </para>
        /// 	<para>
        /// This property is read/write.
        /// </para>
        /// </value>
        /// <remarks>
        /// The image must have time-based frames to animate. All others will ignore this setting.
        /// If the alpha of the control is not full (255) the control can not animate.
        /// If the control is not enabled or not visible the control can not animate.
        /// </remarks>
        [ResourceCategoryAttribute("BehaviorCategory"), ResourceDescriptionAttribute("AllowAnimationDescription"), ResourceDisplayName("DisplayNameAllowAnimation"), DefaultValueAttribute(false)]
        public bool AllowAnimation
        {
            get 
            { 
                return this._allowAnimation;
            
            }

            set 
            {
                if (this._allowAnimation == value)
                {
                    return;

                }

                this._allowAnimation = value;
                this.StartAnimation();
            
            }

        }

        /// <summary>
        /// Gets or sets the border for the control.
        /// </summary>
        /// <value>
        /// 	<para>
        /// Border. An object of type Border representing the control's border width characteristics.
        /// </para>
        /// 	<para>
        /// This property is read/write.
        /// </para>
        /// </value>
        /// <remarks>
        /// For containers such as GradientPanel and GradientCaption, the Border property gets or sets their respective border widths inside the DisplayRectangle.
        /// </remarks>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("BorderDescription"), ResourceDisplayName("DisplayNameBorder"), DefaultValueAttribute(typeof(Border), "1, 1, 1, 1")]
        public new Border Border
        {
            get
            {
                return base.Border;

            }

            set
            {
                base.Border = value;

            }

        }

        /// <summary>
        /// Gets a value indicating whether the control can animate the image.
        /// </summary>
        /// <value>
        /// 	<para>
        /// true if the control is Capable of animating; otherwise, false.
        /// </para>
        /// 	<para>
        /// This property is read only.
        /// </para>
        /// </value>
        /// <remarks>
        /// AllowAnimation does not change this value.
        /// The image must have time-based frames to animate. All others will not animate.
        /// If the alpha of the control is not full (255) the control can not animate.
        /// If the control is not enabled or not visible the control can not animate.
        /// </remarks>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool CanAnimate
        {
            get
            {
                return (base.Enabled && base.Visible && (base.Alpha == 255))?true:false;

            }

        }

        /// <summary>
        /// Gets the default size of the control.
        /// </summary>
        /// <value>
        /// The default Size of the control.
        /// </value>
        protected override System.Drawing.Size DefaultSize
        {
            get
            {
                return new Size(220, 24);

            }

        }

        /// <summary>
        /// Sets or returns the specified foreground color for the style. Typically, this property sets the color for the text. The default value is Empty.
        /// </summary>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("ForeColorDescription"), ResourceDisplayName("DisplayNameForeColor"), DefaultValueAttribute(typeof(Color), "ActiveCaptionText")]
        public override Color ForeColor
        {
            get
            {
                return base.ForeColor;

            }

            set
            {
                if (base.ForeColor == value)
                {
                    return;

                }

                ((GradientCaptionRender)this.GradientRender).ForeColor = value;
                base.ForeColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the gradient high (lighter) color for the control.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.Drawing.Color . A Color that represents the gradient high color of the control.
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("GradientHighColorDescription"), ResourceDisplayName("DisplayNameGradientHighColor"), DefaultValueAttribute(typeof(Color), "GradientActiveCaption")]
        public new Color GradientHighColor
        {
            get
            {
                return base.GradientHighColor;

            }

            set
            {
                base.GradientHighColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the gradient low (darker) color for the control.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.Drawing.Color . A Color that represents the gradient low color of the control.
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("GradientLowColorDescription"), ResourceDisplayName("DisplayNameGradientLowColor"), DefaultValueAttribute(typeof(Color), "ActiveCaption")]
        public new Color GradientLowColor
        {
            get
            {
                return base.GradientLowColor;

            }

            set
            {
                base.GradientLowColor = value;

            }

        }

        /// <summary>
        /// Specifies the direction of a linear gradient.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.Drawing.Drawing2D.LinearGradientMode . Specifies the direction of a linear gradient.
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("GradientModeDescription"), ResourceDisplayName("DisplayNameGradientMode"), DefaultValue(LinearGradientMode.Vertical)]
        public new LinearGradientMode GradientMode
        {
            get
            {
                return base.GradientMode;

            }

            set
            {
                if (value == base.GradientRender.GradientMode)
                {
                    return;

                }

                base.GradientRender.GradientMode = value;

                base.Invalidate();

                base.OnGradientModeChanged(new EventArgs());

            }

        }

        /// <summary>
        /// The image associated with this control.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Drawing.Image . The image associated with this control.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        [ResourceDescriptionAttribute("ImageDescription"), ResourceCategoryAttribute("AppearanceCategory"), ResourceDisplayName("DisplayNameImage"), DefaultValueAttribute(typeof(Image), "(none)")]
        public Image Image
        {
            get
            {
                if ((((GradientCaptionRender)base.GradientRender).Image == null) && (this._imageList != null))
                {
                    if (this._imageIndex != -1)
                    {
                        int imageIndex = this._imageIndex;
                        if (imageIndex >= this._imageList.Images.Count)
                        {
                            imageIndex = this._imageList.Images.Count - 1;

                        }

                        if (imageIndex >= 0)
                        {
                            return this._imageList.Images[imageIndex];

                        }

                    }
                    else
                    {
                        if ((this._imageKey != null) && (this._imageKey.Length > 0))
                        {
                            string imageKey = this._imageKey;

                            if (!this._imageList.Images.ContainsKey(imageKey))
                            {
                                int imageIndex = this._imageList.Images.Count - 1;

                                if (imageIndex >= 0)
                                {
                                    return this._imageList.Images[imageIndex];

                                }

                            }
                            else
                            {
                                return this._imageList.Images[imageKey];

                            }

                        }

                    }

                }

                return ((GradientCaptionRender)base.GradientRender).Image;

            }

            set
            {
                if (((GradientCaptionRender)base.GradientRender).Image != value)
                {

                    this.StopAnimation();
                    try
                    {
                        ((GradientCaptionRender)base.GradientRender).Image = value;

                        if (((GradientCaptionRender)base.GradientRender).Image != null)
                        {
                            this._imageIndex = -1;
                            this._imageKey = string.Empty;
                            this._imageList = null;

                        }

                    }
                    catch
                    {
                        throw;

                    }
                    finally
                    {
                        this.StartAnimation();

                    }

                    base.Invalidate();

                    this.OnImageChanged(new EventArgs());

                }

            }

        }

        /// <summary>
        /// The ContentAlignment associated with this controls image.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Drawing.ContentAlignment . The ContentAlignment associated with this controls image.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("ImageAlignmentDescription"), ResourceDisplayName("DisplayNameImageAlign"), DefaultValueAttribute(ContentAlignment.MiddleRight)]
        public ContentAlignment ImageAlign
        {
            get
            {
                return ((GradientCaptionRender)base.GradientRender).ImageAlign;

            }

            set
            {
                if (value == ((GradientCaptionRender)base.GradientRender).ImageAlign)
                {
                    return;

                }

                ((GradientCaptionRender)base.GradientRender).ImageAlign = value;

                base.Invalidate(true);

                this.OnImageAlignChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the image list index value of the image displayed on the control. 
        /// </summary>
        [RefreshProperties(RefreshProperties.Repaint), ResourceCategoryAttribute("AppearanceCategory"), ResourceDisplayName("DisplayNameImageIndex"), TypeConverter(typeof(ImageIndexConverter)), Editor("System.Windows.Forms.Design.ImageIndexEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), Localizable(true), ResourceDescriptionAttribute("ImageIndexDescription"), DefaultValue(-1)]
        public int ImageIndex
        {
            get
            {
                if (((this._imageIndex != -1) && (this._imageList != null)) && (this._imageIndex >= this._imageList.Images.Count))
                {
                    return (this._imageList.Images.Count - 1);

                }

                return this._imageIndex;

            }

            set
            {
                if (this._imageIndex != value)
                {
                    ((GradientCaptionRender)base.GradientRender).Image = null;
                    this._imageKey = string.Empty;

                    this._imageIndex = value;

                    base.Invalidate(true);

                }

            }

        }

        /// <summary>
        /// Gets or sets the key for the image that is displayed for the control.
        /// </summary>
        [DefaultValue(""), ResourceCategoryAttribute("AppearanceCategory"), ResourceDisplayName("DisplayNameImageKey"), TypeConverter(typeof(ImageKeyConverter)), Editor("System.Windows.Forms.Design.ImageIndexEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), Localizable(true), RefreshProperties(RefreshProperties.Repaint), ResourceDescriptionAttribute("ImageIndexDescription")]
        public string ImageKey
        {
            get
            {
                if (((!String.IsNullOrEmpty(this._imageKey)) && (this._imageList != null)) && (!this._imageList.Images.ContainsKey(this._imageKey)))
                {
                    return this._imageList.Images.Keys[(this._imageList.Images.Count - 1)];

                }

                return this._imageKey;

            }

            set
            {
                if (this._imageKey != value)
                {
                    if (!(string.IsNullOrEmpty(this._imageKey) && (value == "(none)")))
                    {
                        if (value != null)
                        {
                            ((GradientCaptionRender)base.GradientRender).Image = null;
                            this._imageIndex = -1;

                        }

                        if (value == "(none)")
                        {
                            ((GradientCaptionRender)base.GradientRender).Image = null;
                            this._imageIndex = -1;
                            this._imageKey = string.Empty;

                        }
                        else
                        {
                            this._imageKey = value;

                        }

                        base.Invalidate(true);

                    }

                }

            }

        }

        /// <summary>
        /// Gets or sets the ImageList that contains the Image displayed on the control. 
        /// </summary>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("ImageListDescription"), ResourceDisplayName("DisplayNameImageList"), DefaultValueAttribute(typeof(ImageList), "(none)")]
        public ImageList ImageList
        {
            get
            {
                return this._imageList;

            }

            set
            {
                if (this._imageList != value)
                {
                    EventHandler imageListRecreateHandleHandler = new EventHandler(this.ImageListRecreateHandle);
                    EventHandler detachImageListHandler = new EventHandler(this.DetachImageList);

                    if (this._imageList != null)
                    {
                        this._imageList.RecreateHandle -= imageListRecreateHandleHandler;
                        this._imageList.Disposed -= detachImageListHandler;

                    }

                    if (value != null)
                    {
                        ((GradientCaptionRender)base.GradientRender).Image = null;

                    }

                    this._imageList = value;

                    if (value != null)
                    {
                        value.RecreateHandle += imageListRecreateHandleHandler;
                        value.Disposed += detachImageListHandler;

                    }

                    base.Invalidate(true);

                }


            }

        }

        /// <summary>
        /// Gets a value indicating whether the control is currently animating the image.
        /// </summary>
        /// <value>
        /// 	<para>
        /// true if the control is currently animating; otherwise, false.
        /// </para>
        /// 	<para>
        /// This property is read only.
        /// </para>
        /// </value>
        /// <remarks>
        /// The image must have time-based frames to animate. All others will not animate.
        /// If the alpha of the control is not full (255) the control can not animate.
        /// If the control is not enabled or not visible the control can not animate.
        /// </remarks>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool IsAnimating
        {
            get
            {
                return this._isAnimating;

            }

        }

        /// <summary>
        /// Gets or sets the text associated with this control.
        /// </summary>
        /// <value>
        /// <para>
        /// System.String . The text associated with this control.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        [ResourceDescriptionAttribute("TextDescription"), ResourceCategoryAttribute("AppearanceCategory"), ResourceDisplayName("DisplayNameText"), DefaultValueAttribute(""), BrowsableAttribute(true)]
        public override string Text
        {
            get
            {
                return ((GradientCaptionRender)base.GradientRender).Text;

            }

            set
            {
                if (value == null) value = string.Empty;

                if (value == ((GradientCaptionRender)base.GradientRender).Text)
                {
                    return;

                }

                ((GradientCaptionRender)base.GradientRender).Text = value;
                this.OnAutoSizeNeeded(EventArgs.Empty);

                base.Invalidate();

            }

        }

        /// <summary>
        /// The ContentAlignment associated with this controls text.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Drawing.ContentAlignment . The ContentAlignment associated with this controls text.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("TextAlignmentDescription"), ResourceDisplayName("DisplayNameTextAlign"), DefaultValueAttribute(ContentAlignment.MiddleLeft)]
        public ContentAlignment TextAlign
        {
            get
            {
                return ((GradientCaptionRender)base.GradientRender).TextAlign;

            }

            set
            {
                if (value == ((GradientCaptionRender)base.GradientRender).TextAlign)
                {
                    return;

                }

                ((GradientCaptionRender)base.GradientRender).TextAlign = value;

                base.Invalidate();

                this.OnTextAlignChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets a value that determines whether to use the compatible text rendering engine (GDI+) or not (GDI). 
        /// </summary>
        /// <value>
        /// true if the compatible text rendering engine (GDI+) is used; otherwise, false. 
        /// </value>
        [ResourceCategoryAttribute("BehaviorCategory"), ResourceDescriptionAttribute("UseCompatibleTextRenderingDescription"), ResourceDisplayName("DisplayNameUseCompatibleTextRendering"), DefaultValueAttribute(false)]
        public bool UseCompatibleTextRendering
        {
            get 
            {
                return ((GradientCaptionRender)base.GradientRender).UseCompatibleTextRendering;
            
            }

            set 
            {
                if (value == ((GradientCaptionRender)base.GradientRender).UseCompatibleTextRendering)
                {
                    return;

                }

                ((GradientCaptionRender)base.GradientRender).UseCompatibleTextRendering = value;

                base.Invalidate();

            }

        }

        /// <summary>
        /// Gets or sets a value indication whether to hide prefix in text.
        /// </summary>
        [ResourceCategoryAttribute("BehaviorCategory"), ResourceDescriptionAttribute("HidePrefixDescription"), ResourceDisplayName("DisplayNameHidePrefix"), DefaultValueAttribute(false)]
        public bool HidePrefix
        {
            get
            {
                return ((GradientCaptionRender)base.GradientRender).HidePrefix;

            }

            set 
            {
                ((GradientCaptionRender)base.GradientRender).HidePrefix = value;

            }

        }

        /// <summary>
        /// Gets or sets a value indicating whether the control is automatically resized to display its entire contents.
        /// </summary>
        /// <value>
        /// true if the control adjusts its width to closely fit its contents; otherwise, false. The default is false.
        /// </value>
        [ResourceCategoryAttribute("LayoutCategory"), ResourceDescriptionAttribute("AutoSizeDescription"), ResourceDisplayName("DisplayNameAutoSize"), DefaultValueAttribute(false), Browsable(true)]
        public override bool AutoSize
        {
            get
            {
                return base.AutoSize;

            }

            set
            {
                base.AutoSize = value;

                this.OnAutoSizeNeeded(EventArgs.Empty);

            }

        }

        /// <summary>
        /// Initializes a new instance of the GradientCaption class.
        /// </summary>
        public GradientCaption() : base()
        {
            this._imageIndex = -1;
            base.BorderColor = new BorderColor(SystemColors.ActiveCaption);

        }

        /// <summary>
        /// Initializes the class used for rendering. 
        /// Rendering class must be based on IGradientReder.
        /// </summary>
        protected override void InitializeRender()
        {
            base.GradientRender = new GradientCaptionRender();

            GradientCaptionRender render = base.GradientRender as GradientCaptionRender;
            render.Font = this.Font;

            base.ForeColor = SystemColors.ActiveCaptionText;

        }

        /// <summary>
        /// Changes the size of the control (if needed) to fit the content.
        /// </summary>
        internal void SetAutoSize()
        {
            GradientCaptionRender render = base.GradientRender as GradientCaptionRender;
            Size size = render.GetAutoSize();

            this.Width = size.Width;
            this.Height = size.Height;

        }

        /// <summary>
        /// Starts animation of image.
        /// </summary>
        internal void StartAnimation()
        {
            this.StartAnimation((this.CanAnimate && this._allowAnimation));

        }

        private void StartAnimation(bool animate)
        {
            if (!this.DesignMode)
            {
                if (animate != this._isAnimating)
                {
                    if (animate)
                    {
                        if (((GradientCaptionRender)base.GradientRender).Image != null)
                        {
                            ImageAnimator.Animate(((GradientCaptionRender)base.GradientRender).Image, new EventHandler(this.OnFrameChanged));
                            this._isAnimating = animate;

                        }

                    }
                    else if (((GradientCaptionRender)base.GradientRender).Image != null)
                    {
                        ImageAnimator.StopAnimate(((GradientCaptionRender)base.GradientRender).Image, new EventHandler(this.OnFrameChanged));
                        this._isAnimating = animate;

                    }

                }

            }

        }

        /// <summary>
        /// Stops animation of image.
        /// </summary>
        internal void StopAnimation()
        {
            this.StartAnimation(false);

        }

        private void OnFrameChanged(object sender, EventArgs e)
        {
            if (base.InvokeRequired)
            {
                if (!this.Disposing && !this._disposed)
                {                    
                    base.BeginInvoke(new EventHandler(this.OnFrameChanged), new object[] { sender, e });

                }

            }
            else
            {
                ImageAnimator.UpdateFrames();

                base.Invalidate();

            }

        }

        /// <summary>
        /// Raises the ForeColorChanged event. 
        /// </summary>
        /// <param name="e">An System.EventArgs that contains the event data.</param>
        protected override void OnForeColorChanged(System.EventArgs e)
        {
            ((GradientCaptionRender)this.GradientRender).ForeColor = this.ForeColor;

            base.OnForeColorChanged(e);

        }

        /// <summary>
        /// Releases the unmanaged resources used by the GradientPanel and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(System.Boolean disposing)
        {
            try
            {
                if (!this._disposed)
                {
                    if (disposing)
                    {
                        this.StopAnimation();

                        ((GradientCaptionRender)base.GradientRender).Dispose();

                        if (this._imageList != null)
                        {
                            this._imageList.Disposed -= new EventHandler(this.DetachImageList);
                            this._imageList.RecreateHandle -= new EventHandler(this.ImageListRecreateHandle);

                            this._imageList = null; //Do not dispose may be used by other controls

                        }

                    }

                }

                this._disposed = true;

            }
            catch
            {
                throw;

            }
            finally
            {
                base.Dispose(disposing);

            }

        }

        private void DetachImageList(object sender, EventArgs e)
        {
            this._imageList = null;

        }

        /// <summary>
        /// Fires the event indicating that control image has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnImageChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected virtual void OnImageChanged(EventArgs e)
        {
            this.OnAutoSizeNeeded(EventArgs.Empty);

            if (this.ImageChanged != null)
            {
                this.ImageChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that control image alignment has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnImageAlignChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected virtual void OnImageAlignChanged(EventArgs e)
        {
            if (this.ImageAlignChanged != null)
            {
                this.ImageAlignChanged(this, e);

            }

        }

        ///<summary>
        /// Raises the FontChanged event.
        /// </summary>
        /// <param name="e">An System.EventArgs that contains the event data.</param>
        protected override void OnFontChanged(System.EventArgs e)
        {
            ((GradientCaptionRender)this.GradientRender).Font = this.Font;
            this.OnAutoSizeNeeded(EventArgs.Empty);

            base.OnFontChanged(e);

        }

        /// <summary>
        /// Fires the event indicating that control text alignment has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnTextAlignChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected virtual void OnTextAlignChanged(EventArgs e)
        {
            if (this.TextAlignChanged != null)
            {
                this.TextAlignChanged(this, e);

            }

        }

        private void ImageListRecreateHandle(object sender, EventArgs e)
        {
            if (base.IsHandleCreated)
            {
                base.Invalidate();

            }

        }

        /// <summary>
        /// Raises the Paint event.
        /// </summary>
        /// <param name="e">A System.Windows.Forms.PaintEventArgs that contains the event data.</param>
        /// <remarks>
        /// <para>
        /// Raising an event invokes the event handler through a delegate. For more information, Raising an Event.
        /// </para>
        /// <para>
        /// The OnPaint method also allows derived classes to handle the event without attaching a delegate. This is the preferred technique for handling the event in a derived class.
        /// </para>
        /// <para>
        /// Note for Inheritors:
        /// When overriding OnPaint in a derived class, be sure to call the base class's OnPaint method so that registered delegates receive the event.
        /// </para>
        /// </remarks>
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            if ((this._imageIndex != -1) || (!string.IsNullOrEmpty(this._imageKey)))
            {
                ((GradientCaptionRender)base.GradientRender).IsImageFromImageList = true;

            }
            else
            {
                ((GradientCaptionRender)base.GradientRender).IsImageFromImageList = false;

            }

            if (((GradientCaptionRender)base.GradientRender).Image == null)
            {
                ((GradientCaptionRender)base.GradientRender).Image = this.Image;

            }

            base.OnPaint(e);

        }

        /// <summary>
        /// Called when a auto size change may be needed.
        /// </summary>
        /// <param name="e">An System.EventArgs that contains the event data.</param>
        protected void OnAutoSizeNeeded(EventArgs e)
        {
            if (base.AutoSize)
            {
                this.SetAutoSize();

            }

        }

        /// <summary>
        /// Raises the EnabledChanged event.
        /// </summary>
        /// <param name="e">An System.EventArgs that contains the event data.</param>        
        protected override void OnEnabledChanged(System.EventArgs e)
        {
            base.OnEnabledChanged(e);

            this.StartAnimation();

        }

        /// <summary>
        /// Raises the VisibleChanged event.
        /// </summary>
        /// <param name="e">An System.EventArgs that contains the event data.</param>
        protected override void OnVisibleChanged(System.EventArgs e)
        {
            base.OnVisibleChanged(e);

            this.StartAnimation();

        }

        /// <summary>
        /// Raises the RightToLeftChanged event.
        /// </summary>
        /// <param name="e">An System.EventArgs that contains the event data.</param>
        protected override void OnRightToLeftChanged(System.EventArgs e)
        {            
            base.OnRightToLeftChanged(e);

            if (this.RightToLeft == RightToLeft.Yes)
            {
                ((GradientCaptionRender)base.GradientRender).RightToLeft = true;

            }
            else
            {
                ((GradientCaptionRender)base.GradientRender).RightToLeft = false;

            }

        }

    }

}
